using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using HtmlAgilityPack;
using Microsoft.Phone.Scheduler;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using MVBuddy.Common.Helpers;
using MVBuddy.Common.Model;
using MVBuddy.Common.Resources;
using MVBuddy.Messages;
using MVBuddy.TaskAgent;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;

namespace MVBuddy.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private UserData userData;
        private UserData UserData
        {
            get
            {
                return this.userData;
            }
            set
            {
                if (this.userData != value)
                {
                    this.userData = value;
                    RaisePropertyChanged(() => this.UserData);
                    RaisePropertyChanged(() => this.NotificationData);
                }
            }
        }

        public string Username
        {
            get
            {
                return this.userData.Username;
            }
            set
            {
                if (this.userData.Username != value)
                {
                    this.userData.Username = value;
                    RaisePropertyChanged(() => this.Username);
                }
            }
        }

        public string Password
        {
            get
            {
                return this.userData.Password;
            }
            set
            {
                if (this.userData.Password != value)
                {
                    this.userData.Password = value;
                    RaisePropertyChanged(() => this.Password);
                }
            }
        }

        public bool SaveLogin
        {
            get
            {
                return this.userData.SaveLogin;
            }
            set
            {
                if (this.userData.SaveLogin != value)
                {
                    this.userData.SaveLogin = value;
                    this.EnableAgent = this.EnableAgent && value;
                    RaisePropertyChanged(() => this.SaveLogin);
                }
            }
        }

        public bool EnableAgent
        {
            get
            {
                return this.userData.EnableAgent;
            }
            set
            {
                if (this.userData.EnableAgent != value)
                {
                    this.userData.EnableAgent = value;
                    this.ShowToasts = this.ShowToasts && value;
                    RaisePropertyChanged(() => this.EnableAgent);

                    if (this.userData.EnableAgent)
                    {
                        RegisterAgent();
                    }
                    else
                    {
                        UnregisterAgent();
                    }
                }
            }
        }

        public bool ShowToasts
        {
            get
            {
                return this.userData.ShowToasts;
            }
            set
            {
                if (this.userData.ShowToasts != value)
                {
                    this.userData.ShowToasts = value;
                    RaisePropertyChanged(() => this.ShowToasts);
                }
            }
        }

        public NotificationData NotificationData
        {
            get
            {
                return this.userData.NotificationData;
            }
            set
            {
                if (this.userData.NotificationData != value)
                {
                    this.userData.NotificationData = value;
                    RaisePropertyChanged(() => this.NotificationData);
                }
            }
        }

        public MainViewModel()
        {
            if (this.IsInDesignMode)
            {
                this.UserData = new UserData()
                {
                    NotificationData = new NotificationData()
                    {
                        FavoriteCount = 1,
                        MessageCount = 0,
                        NotificationCount = 3,
                    },
                    Username = "TestUser",
                    Password = string.Empty,
                    SaveLogin = true,
                    ShowToasts = false,
                    EnableAgent = false,
                };
            }
            else
            {
                this.UserData = StorageManager.LoadAppSetting<UserData>("UserData");

                if (this.UserData == null)
                {
                    this.UserData = new UserData();
                }

                Messenger.Default.Register<RequestLoginMessage>(this, RequestLoginMessageReceived);
                Messenger.Default.Register<RequestWebBrowserMessage>(this, RequestWebBrowserMessageReceived);
                Messenger.Default.Register<CheckCredentialsStoredMessage>(this, CheckCredentialsStoredMessageReceived);
            }
        }

        private async void RequestLoginMessageReceived(RequestLoginMessage message)
        {
            HtmlRequest loginRequest = new HtmlRequest(new Uri("http://m.mediavida.com/login.php"), "POST", "application/x-www-form-urlencoded", new System.Collections.Generic.Dictionary<string, string>()
                {
                    { "name", this.Username },
                    { "password", this.Password },
                });

            HtmlDocument document = await loginRequest.DoRequest();

            if (document != null)
            {
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    this.NotificationData = NotificationData.FromHtmlDocument(document);

                    if (this.NotificationData != null)
                    {
                        StorageManager.SaveAppSetting("UserData", this.UserData);

                        if (ShellTile.ActiveTiles.ToList().Count >= 1)
                        {
                            ShellTile tile = ShellTile.ActiveTiles.ElementAtOrDefault(0);
                            string tilePath = "/Shared/ShellContent/TileBackBackground.jpg";

                            WriteableBitmap backBitmap = this.UserData.RenderUserDataForBackgroundTile();
                            StorageManager.SaveShellBitmapAsJpeg(tilePath, backBitmap);

                            tile.Update(new StandardTileData()
                            {
                                BackTitle = string.Empty,
                                Count = this.UserData.NotificationData.NotificationCount + this.UserData.NotificationData.FavoriteCount + this.UserData.NotificationData.MessageCount,
                                BackContent = string.Empty,
                                BackBackgroundImage = new Uri("isostore:" + tilePath, UriKind.Absolute),
                            });
                        }

                        Messenger.Default.Send(new LoginSuccessfulMessage());
                    }
                    else
                    {
                        this.Username = string.Empty;
                        this.Password = string.Empty;
                        this.SaveLogin = false;
                        Messenger.Default.Send(new LoginFailedMessage(AppResources.IncorrectLoginError));
                    }
                });
            }
            else
            {
                Messenger.Default.Send(new LoginFailedMessage(AppResources.NoInternetConnectionError));
            }
        }

        private void RequestWebBrowserMessageReceived(RequestWebBrowserMessage message)
        {
            WebBrowserTask webTask = new WebBrowserTask();
            webTask.Uri = new Uri(message.Notification);
            webTask.Show();
        }

        private void CheckCredentialsStoredMessageReceived(CheckCredentialsStoredMessage message)
        {
            if (this.UserData.SaveLogin == true)
            {
                Messenger.Default.Send<CredentialsStoredMessage>(new CredentialsStoredMessage());
            }
            else
            {
                this.UserData.Username = string.Empty;
                this.UserData.Password = string.Empty;
            }
        }

        private void RegisterAgent()
        {
            PeriodicTask periodicTask = new PeriodicTask(ScheduledAgent.TaskName);
            periodicTask.Description = AppResources.BackgroundAgentDescription;
            periodicTask.ExpirationTime = DateTime.Now + TimeSpan.FromDays(7);

            try
            {
                UnregisterAgent();

                ScheduledActionService.Add(periodicTask);
            }
            catch (InvalidOperationException exception)
            {
                if (exception.Message.Contains("exists already"))
                {
                    MessageBox.Show("The background agent is already running.");
                }
                if (exception.Message.Contains("BNS Error: The action is disabled"))
                {
                    MessageBox.Show("Background processes for this application have been prohibited.");
                }
                if (exception.Message.Contains("BNS Error: The maximum number of ScheduledActions of this type has already been added."))
                {
                    MessageBox.Show("Background agent exceeded hardware limitations.");
                }
            }
            catch (SchedulerServiceException)
            {
            }

#if DEBUG
            ScheduledActionService.LaunchForTest(ScheduledAgent.TaskName, TimeSpan.FromSeconds(15));
#endif
        }

        private void UnregisterAgent()
        {
            if (ScheduledActionService.Find(ScheduledAgent.TaskName) != null)
            {
                ScheduledActionService.Remove(ScheduledAgent.TaskName);
            }
        }
    }
}